/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 */

#include "userConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "usart.h"

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   256
TaskHandle_t    start_task_handler;

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   256
TaskHandle_t    task1_handler;

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   256
TaskHandle_t    task2_handler;

EventGroupHandle_t  eventgroup_handle;
#define EVENTBIT_0  (1 << 0)
#define EVENTBIT_1  (1 << 1)


/* 任务一，释放二值信号量 */
static void task1(void * pvParameters)
{
    uint8_t pingPang = 0;

    while(1)
    {
        if (pingPang == 0) {
            pingPang = 1;
            xEventGroupSetBits(eventgroup_handle, EVENTBIT_0); /* 将事件标志组的bit0位置1 */
        } else {
            pingPang = 0;
            xEventGroupSetBits(eventgroup_handle, EVENTBIT_1); /* 将事件标志组的bit1位置1 */
        }
        vTaskDelay(100);
    }
}

/* 任务二，获取二值信号量 */
static void task2(void * pvParameters)
{
    EventBits_t event_bit = 0;
    while(1)
    {
        event_bit = xEventGroupWaitBits(eventgroup_handle,         /* 事件标志组句柄 */
                                         EVENTBIT_0 | EVENTBIT_1,   /* 等待事件标志组的bit0和bit1位 */
                                         pdTRUE,                    /* 成功等待到事件标志位后，清除事件标志组中的bit0和bit1位 */
                                         pdTRUE,                    /* 等待事件标志组的bit0和bit1位都置1,就成立 */
                                         portMAX_DELAY);           /* 死等 */
        usart_transmit("等待到的事件标志位值为：%#x\r\n", event_bit);
    }
}

static void start_task(void * pvParameters)
{
    taskENTER_CRITICAL();
    eventgroup_handle = xEventGroupCreate();
    if(eventgroup_handle != NULL)
    {
        usart_transmit("事件标志组创建成功!!\r\n");
    }

    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );

    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler);

    vTaskDelete(NULL);

    taskEXIT_CRITICAL();
}

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void event_group(void)
{
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler);

    vTaskStartScheduler();
}